import threading
import time
import queue
import random

#-----------------------------通过threading的Thread方法创建线程------------------
# def action(max):
#     for i in range(max):
#         print(threading.current_thread().getName()+" "+str(i))
# print(threading.current_thread().getName() +"主线程开始")
# for i in range(5):
#     if i==0:
#         t1=threading.Thread(target=action,args=(5,))
#         t1.start()
#         t2=threading.Thread(target=action,args=(5,))
#         t2.start()
# print("主线程执行完毕")

#--------------------------------继承Thread类来创建线程------------------------------

# class Threadme(threading.Thread):
#     def __init__(self,num):
#         threading.Thread.__init__(self)
#         self.num=num
#
#     def run(self) :
#         for x in range(0,self.num):
#             print(threading.current_thread().getName()+":"+str(x))
#
# if __name__=="__main__":
#     print("主线程开始")
#     t1=Threadme(5)
#     t1.start()
#     t2=Threadme(5)
#     t2.start()
#     print("主线程结束")

# --------------------------------------重入锁和非重入锁--------------------------------
# class ThreadReentrant(threading.Thread):
#     def __init__(self,num1,num2):
#         threading.Thread.__init__(self)
#         # 不可重入锁（会导致线程死锁），加锁以后不可再次加锁
#         # self.lock=threading.Lock()
#         # 可重入锁，同一个线程申请锁的时候可以重复加锁，有个锁计数器
#         self.lock=threading.RLock()
#         self.num1=num1
#         self.num2=num2
#         print("线程类-可重入锁-初始化")
#     def __del__(self):
#         print("线程类-可重入锁-销毁")
#
#     def run(self) :
#         self.printB()
#
#     def printA(self):
#         self.lock.acquire()
#         try:
#             for a in range(0,self.num1):
#                 print(threading.current_thread().getName()+"-num1:"+str(a))
#         finally:
#             self.lock.release()
#
#     def printB(self):
#         self.lock.acquire()
#         try:
#             self.printA()
#             for b in range(0,self.num2):
#                 print(threading.current_thread().getName()+"-num2:"+str(b))
#         finally:
#             self.lock.release()
#
# rt1=ThreadReentrant(5,10)
# rt1.start()

#----------------------------------------------多线程-------------------------------------
# mylock=threading.RLock()
# class Account:
#     def __init__(self,account):
#         self.account=account
#
# a=Account(1000)
#
# def consumer(ac,num):
#     # if num<=ac.account:
#     #     print(threading.current_thread().getName()+"-取钱成功,取出："+str(num))
#     #     time.sleep(1)
#     #     ac.account = ac.account - num;
#     #     print(threading.current_thread().getName()+"余额："+str(ac.account))
#     try:
#         mylock.acquire()
#         if num<=ac.account:
#             print(threading.current_thread().getName()+"-取钱成功,取出："+str(num))
#             time.sleep(1)
#             ac.account = ac.account - num;
#             print(threading.current_thread().getName()+"余额："+str(ac.account))
#     finally:
#         mylock.release()
#
# t1=threading.Thread(target=consumer,args=(a,800))
# t2=threading.Thread(target=consumer,args=(a,800))
# t1.start()
# t2.start()

# ----------------------------------- 线程死锁，在classA和classB相互调用对方的方法，并且相互等待对方释放资源-----------------
#
#
# class ClassA:
#     def __init__(self):
#         self.lock=threading.RLock()
#
#     # 得到classA的锁，试图得到classB的锁
#     def infoA(self, b):
#         self.lock.acquire()
#         time.sleep(10)
#         b.info()
#         self.lock.release()
#
#     def info(self):
#         self.lock.acquire()
#         print("this is ClassA info")
#         self.lock.release()
#
#
# class ClassB:
#     def __init__(self):
#         self.lock = threading.RLock()
#
#     # 得到classB的锁，试图得到classA的锁
#     def infoB(self, a):
#         self.lock.acquire()
#         time.sleep(10)
#         a.info()
#         self.lock.release()
#
#     def info(self):
#         self.lock.acquire()
#         print("this is ClassB info")
#         self.lock.release()
#
#
# ca=ClassA()
# cb=ClassB()
#
# def funA():
#     ca.infoA(cb)
# def funB():
#     cb.infoB(ca)
#
# # 函数调用不是线程，不会死锁
# # funA()
# # funB()
#
# t1=threading.Thread(target=funA).start()
# t2=threading.Thread(target=funB).start()

# -------------------------------------------------------------wait与notify线程通信--------------------------------------
# class conditionT():
#
#     def __init__(self):
#         self.cond=threading.Condition()
#         print(threading.current_thread().getName()+":线程初始化。。。。。。。。。。。。。。。。。")
#
#     def todo(self,nums,state,times):
#         try:
#             self.cond.acquire()
#             if(state=="wait"):
#                 print("wait "+str(times)+".......")
#                 self.cond.wait(times)
#                 for x in range(0,nums):
#                     print(threading.current_thread().getName()+":"+str(x))
#             if(state=="notify"):
#                 print(str(times)+"s 后唤醒所有的线程......")
#                 self.cond.wait(times)
#                 self.cond.notify_all()
#         finally:
#             self.cond.release()
#
# d=conditionT()
#
# def runfun(td,nums,state,times):
#     print(threading.current_thread().getName() + ":线程初始化。。。。。。。。。。。。。。。。。")
#     td.todo(nums,state,times)
#
#
# t1=threading.Thread(target=runfun,args=(d,5,'wait',1)).start()
# t2=threading.Thread(target=runfun,args=(d,5,'wait',10)).start()
# t3=threading.Thread(target=runfun,args=(d,5,'wait',20)).start()
# t4=threading.Thread(target=runfun,args=(d,5,'notify',5)).start()

def product(bq):
    str_tuple=("python","java","C++")
    i=random.randint(0,2)
    bq.put(str_tuple[i])
    print(threading.current_thread().getName()+":"+str_tuple[i]+"进入队列--------------")
    time.sleep(1)

def consumer(bq):
    i=bq.get()
    print(threading.current_thread().getName()+":"+i+"取出队列--------------")
    time.sleep(1)

bq=queue.Queue(maxsize=1)

t1=threading.Thread(target=product,args=(bq,)).start()
t1=threading.Thread(target=product,args=(bq,)).start()
t1=threading.Thread(target=product,args=(bq,)).start()
t2=threading.Thread(target=consumer,args=(bq,)).start()
t2=threading.Thread(target=consumer,args=(bq,)).start()
t2=threading.Thread(target=consumer,args=(bq,)).start()





